package com.kalix.training.videos.biz;

import com.github.dozermapper.core.DozerBeanMapperBuilder;
import com.github.dozermapper.core.Mapper;
import com.kalix.framework.core.api.exception.KalixRuntimeException;
import com.kalix.framework.core.api.persistence.JsonData;
import com.kalix.framework.core.api.persistence.JsonStatus;
import com.kalix.framework.core.impl.biz.ShiroGenericBizServiceImpl;
import com.kalix.training.videos.api.biz.IVideosBeanService;
import com.kalix.training.videos.api.dao.IVideosBeanDao;
import com.kalix.training.videos.api.dto.SelectDTO;
import com.kalix.training.videos.api.dto.VideosDTO;
import com.kalix.training.videos.api.dto.VideosTreeDTO;
import com.kalix.training.videos.entities.VideosBean;
import org.json.JSONObject;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;

public class VideosBeanServiceImpl extends ShiroGenericBizServiceImpl<IVideosBeanDao, VideosBean>
        implements IVideosBeanService {
//    private String audit;

    @Transactional
    public void doBatchAudit(String entityIds, JsonStatus jsonStatus) {

        dao.removeBatch(entityIds);
        jsonStatus.setSuccess(true);
        jsonStatus.setMsg("批量删除成功！");
    }

    @Override
    public JsonData getVideos(Integer page, Integer limit, String jsonStr) {
        String sql = "select v.id,v.title,c.name as cname,v.hits,v.audit,v.videoUrl,v.cid,c.did,d.content as dname,v.vid from mooc_departments d, mooc_course c, mooc_videos v where v.cid=c.id and c.did=d.id";
        if (jsonStr != null && !jsonStr.isEmpty()) {
            JSONObject obj = new JSONObject(jsonStr);
            for (String str : obj.keySet()) {
                sql += " and v." + str.replace("%", "") + " like '%" + obj.get(str) + "%'";
            }
        }
        JsonData jsondata = new JsonData();
        List<VideosDTO> vplist = dao.findByNativeSql(sql, VideosDTO.class);
        if (vplist.size() > 0) {
            if (page != null && limit != null) {
                List<VideosDTO> list = vplist.subList(page * limit - limit, limit * page > vplist.size() ? vplist.size() : limit * page);
                jsondata.setData(list);
                jsondata.setTotalCount((long) vplist.size());
            } else {
                jsondata.setData(vplist);
                jsondata.setTotalCount((long) vplist.size());
            }
        }
        return jsondata;
    }

    @Override
    public JsonData getDDidBySelect(long did) {
        String sql="select c.id as value,c.name as label from mooc_course c where c.did=" + did ;
        List<SelectDTO> list = dao.findByNativeSql(sql, SelectDTO.class);
        JsonData jsondata = new JsonData();
        jsondata.setData(list);
        jsondata.setTotalCount((long)list.size());
        return jsondata;
    }

    //  根据课程cid查询所有视频信息
    @Override
    public JsonData getVideosByCid(long cid) {
        String hql="select v from VideosBean v where v.cid=" + cid ;
        List<VideosBean> list = dao.find(hql);
        JsonData jsondata = new JsonData();
        jsondata.setData(list);
        jsondata.setTotalCount((long)list.size());
        return jsondata;
    }

    //  根据视频vid查询视频点击量hits
    @Override
    public JsonStatus getVideosByid(long id){
        JsonStatus jsonstatus = new JsonStatus();
        VideosBean v = dao.get(id);
        if (v != null) {
            v.setHits(v.getHits() + 1);
            dao.save(v);
            jsonstatus.setSuccess(true);
            jsonstatus.setMsg("修改成功！");
        } else {
            jsonstatus.setFailure(true);
            jsonstatus.setMsg("修改失败！");
        }
        return jsonstatus;
    }
    @Override
    public void beforeSaveEntity(VideosBean entity, JsonStatus status) {
        Long vid = entity.getVid();
        dao.updateNativeQuery("update mooc_videos set isleaf=0 where id=" + vid);
    }

    @Override
    public VideosTreeDTO getVideosByVid(Long vid, Long cid, String audit) {
        VideosTreeDTO root = new VideosTreeDTO();
        root.setId(-1L);
        List<VideosBean> beans = new ArrayList<>();
        String sql = "select v from VideosBean v where 1=1";
        if (vid != null) {
            if (vid != -1) {
                sql += " and v.vid=" + vid;
            }
        }
        if (audit != null && !audit.equals("")) {
            sql += " and v.audit='" + audit + "'";
        }
        if (cid != null) {
            sql += " and v.cid=" + cid;
        }
        sql += " order by v.cid, v.sequence";
        beans = dao.find(sql);
        if (beans != null && beans.size() > 0) {
            List<VideosBean> rootElements = getRootElements(beans);
            if (rootElements != null && rootElements.size() > 0) {
                for (VideosBean rootElement : rootElements) {
//                    Mapper mapper = new DozerBeanMapper();
                    Mapper mapper = DozerBeanMapperBuilder.buildDefault();
                    VideosTreeDTO videosTreeDTO = mapper.map(rootElement, VideosTreeDTO.class);
                    videosTreeDTO.setLeaf(rootElement.getIsLeaf() == 0 ? false : true);
                    videosTreeDTO.setVideosName("根目录");
                    getChilden(videosTreeDTO, beans, mapper);
                    root.getChildren().add(videosTreeDTO);
                }
            }
        }
        return root;
    }

    @Override
    public JsonStatus deleteAllVideos(long id) {
        dao.remove(id);
        deleteAllChildens(id);
        JsonStatus jsonStatus = new JsonStatus();
        jsonStatus.setSuccess(true);
        jsonStatus.setMsg("删除成功！");
        return jsonStatus;
    }

    /**
     * 用递归的方法删除节点下的所有子节点
     *
     * @param id
     */
    private void deleteAllChildens(long id) {
        List<VideosBean> list = dao.find("select v from VideosBean v");
        for (VideosBean dep : list) {
            if (dep.getVid() == id) {
                dao.remove(dep.getId());
                deleteAllChildens(dep.getId());
            }
        }
    }

    /**
     * 递归函数加载子节点
     *
     * @param root
     * @param elements
     */
    private void getChilden(VideosTreeDTO root, List<VideosBean> elements, Mapper mapper) {
        List<VideosTreeDTO> children = new ArrayList<VideosTreeDTO>();
        for (VideosBean videosBean : elements) {
            if (root.getId() != -1 && (root.getId() == videosBean.getVid())) {
                VideosTreeDTO videosTreeDTO = mapper.map(videosBean, VideosTreeDTO.class);
                videosTreeDTO.setLeaf(videosBean.getIsLeaf() == 0 ? false : true);
                videosTreeDTO.setVideosName(root.getTitle());
                children.add(videosTreeDTO);
                if (videosBean.getIsLeaf() == 0) {
                    getChilden(videosTreeDTO, elements, mapper);
                }
            }
        }
        root.setChildren(children);
    }

    /**
     * 获得所有根节点
     *
     * @param elements
     * @return
     */
    private List<VideosBean> getRootElements(List<VideosBean> elements) {
        List<VideosBean> roots = new ArrayList<VideosBean>();
        for (VideosBean element : elements) {
            if (element.getVid() == -1) {
                roots.add(element);
            }
        }
        return roots;
    }

//    private String getVid(long did) {
//        VideosBean videos = dao.get(did);
//        String str = did + ",";
//        if (videos.getVid() != -1) {
//            str += getVid(videos.getVid());
//        }
//        return str;
//    }

    @Override
    public int uploadVideoById(long id,String videoUrl) {
        String sql = "update VideosBean v set v.videoUrl ='" +videoUrl+ "' where v.id = " + id;
        return dao.update(sql);
    }

    @Override
    public int deleteVideoById(long id) {
        String sql = "update VideosBean v set v.videoUrl = null where v.id = " + id;
        return dao.update(sql);
    }
}
